package com.java.common;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * png图形验证码
 * 基于cookie+ehcache
 * 
 * @author wqf
 */
public class ImageCaptchaService {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	
	private final static String COOKIE_NAME = "_captcha_key_"; 
	private static int WIDTH = 120;
	private static int HEIGHT = 40;
	private static int LENGTH = 5;
	private final static Random random = new Random();
	
	/**
	 * 生成验证码
	 * @param req
	 * @param res
	 * @throws IOException 
	 */
	public static void get(HttpServletRequest request, HttpServletResponse response) throws IOException{
		response.setContentType("image/jpeg");		
		//禁止图像缓存
        response.setHeader("Pragma","No-cache");
        response.setHeader("Cache-Control","no-cache");
        response.setDateHeader("Expires", 0);
		_Render(_GenerateCaptchaCode(request), response.getOutputStream(), WIDTH, HEIGHT);
	}
	
	/**
	 * 检查验证码是否正确
	 * @param req
	 * @return
	 */
	public static boolean validate(HttpServletRequest req,String code) {
		Object validateCode = req.getSession().getAttribute(COOKIE_NAME);
		if(validateCode != null && code.equalsIgnoreCase(validateCode.toString())) {
			return true;
		}
		return false;		
	}
	
	/**
	 * 生成验证码并放入缓存
	 * @param ctx
	 * @return
	 */
	private static String _GenerateCaptchaCode(HttpServletRequest request) {
		String code = RandomStringUtils.randomAlphanumeric(LENGTH).toUpperCase();
		//屏蔽不易识别的字母
		code.replace('0', 'W');
		code.replace('o', 'R');
		code.replace('I', 'E');
		code.replace('1', 'T');
		request.getSession().setAttribute(COOKIE_NAME,code);
		return code;
	}
	
    /**
     * 渲染生成随机码图片
     * @param text 验证码字符
     * @param out 输出流
     * @param width 图片宽
     * @param height 图片高
     * @throws IOException
     */
    private static void _Render(String text, OutputStream out, int width, int height) throws IOException {
	    BufferedImage bi = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);//在内存中创建图像
	    Graphics2D g = (Graphics2D)bi.getGraphics();//获取图型上下文
	    
	    g.setColor(Color.WHITE);//背景色
	    g.fillRect(0,0,width,height);//图片大小
	    //画10个背景圆圈
	    for(int i=0;i<10;i++){
	    	g.setColor(_GetRandColor(150, 250));
	    	g.drawOval(random.nextInt(110), random.nextInt(24), 5+random.nextInt(10), 5+random.nextInt(10));
	    }
	    //设置字体
	    Font mFont = new Font("Arial", Font.ITALIC, 28);
	    g.setFont(mFont);
	    g.setColor(_GetRandColor(10,240));
	    g.drawString(text, 10, 30);
	    
	    // Caused by: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。
//	    ImageIO.write(bi, "png", out);
	    ImageIO.write(bi, "JPEG", out);
    }
    
    /**
     * 给定范围获得随机颜色
     * @param fc
     * @param bc
     * @return
     */
    private static Color _GetRandColor(int fc,int bc){
		if (fc > 255) fc = 255;
		if (bc > 255) bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

    public static void main(String[] args) throws IOException {
    	for(int i=0;i<100;i++){
    		
    	String code = RandomStringUtils.randomAlphanumeric(LENGTH).toUpperCase();
		code = code.replace('0', 'W');
		code = code.replace('o', 'R');
		code = code.replace('I', 'E');
		code = code.replace('1', 'T');
		
    	FileOutputStream out = new FileOutputStream("d:\\temp\\aa"+i+".jpg");    	
    	_Render(code,out,120,40);
    	
		}
    }
    
}
